﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace YJKColumnModify.ConnectColumnBream
{
	public class SelectBream
	{
		public SelectBream(ExternalCommandData commandData)
		{
			this.m_commandData = commandData;
			this.m_uiDoc = commandData.Application.ActiveUIDocument;
			this.m_doc = this.m_uiDoc.Document;
			this.m_view = this.m_doc.ActiveView;
			this.m_lstDocBream = this.GetBreamOnDoc();
		}

		public int GetBreamOfLevel(ref List<BreamInfo> lstInfo)
		{
			List<BreamInfo> list = new List<BreamInfo>();
			ViewPlan viewPlan = this.m_view as ViewPlan;
			if (viewPlan == null)
			{
				lstInfo = list;
				return -1;
			}
            double num = (this.m_doc.GetElement(viewPlan.GetViewRange().GetLevelId((PlanViewPlane)0)) as Level).Elevation + viewPlan.GetViewRange().GetOffset((PlanViewPlane)0);
            double num2 = (this.m_doc.GetElement(viewPlan.GetViewRange().GetLevelId((PlanViewPlane)3)) as Level).Elevation + viewPlan.GetViewRange().GetOffset((PlanViewPlane)3);
			foreach (FamilyInstance familyInstance in this.m_lstDocBream)
			{
				XYZ endPoint;
				XYZ endPoint2;
				if ((familyInstance.Location as LocationCurve).Curve.GetEndPoint(0).Z <= (familyInstance.Location as LocationCurve).Curve.GetEndPoint(1).Z)
				{
					endPoint = (familyInstance.Location as LocationCurve).Curve.GetEndPoint(0);
					endPoint2 = (familyInstance.Location as LocationCurve).Curve.GetEndPoint(1);
				}
				else
				{
					endPoint = (familyInstance.Location as LocationCurve).Curve.GetEndPoint(1);
					endPoint2 = (familyInstance.Location as LocationCurve).Curve.GetEndPoint(0);
				}
				double num3 = endPoint.Z;
				double num4 = endPoint2.Z;
				IList<Parameter> parameters = familyInstance.GetParameters("Z 轴偏移值");
				if (parameters.Count != 0)
				{
					Parameter parameter = parameters.First<Parameter>();
					if (parameter != null && parameter.HasValue)
					{
						num3 += parameter.AsDouble();
						num4 += parameter.AsDouble();
					}
				}
				if (num3 >= num2 && num4 <= num)
				{
					BreamInfo item = new BreamInfo(this.m_commandData, familyInstance, viewPlan);
					list.Add(item);
				}
			}
			lstInfo = list;
			return lstInfo.Count;
		}

		public int GetBreamOfBuild(ref List<BreamInfo> lstInfo)
		{
			new List<Level>();
			Dictionary<Level, double> docLevel = new Dictionary<Level, double>();
			Dictionary<ViewPlan, Level> dictionary = new Dictionary<ViewPlan, Level>();
			List<BreamInfo> list = new List<BreamInfo>();
			docLevel = this.GetDocLevel();
			dictionary = this.GetDocViewPlan();
			foreach (FamilyInstance bream in this.m_lstDocBream)
			{
				Level breamTopLevel = this.GetBreamTopLevel(bream, docLevel);
				bool flag = false;
				foreach (KeyValuePair<ViewPlan, Level> keyValuePair in dictionary)
				{
					if (keyValuePair.Value != null)
					{
						try
						{
							if (keyValuePair.Value.Id.IntegerValue == breamTopLevel.Id.IntegerValue && this.IsLookElement(bream, keyValuePair.Key))
							{
								BreamInfo item = new BreamInfo(this.m_commandData, bream, keyValuePair.Key);
								list.Add(item);
								flag = true;
								break;
							}
						}
						catch
						{
							break;
						}
					}
				}
				if (!flag)
				{
					foreach (KeyValuePair<ViewPlan, Level> keyValuePair2 in dictionary)
					{
						if (this.IsLookElement(bream, keyValuePair2.Key))
						{
							BreamInfo item2 = new BreamInfo(this.m_commandData, bream, keyValuePair2.Key);
							list.Add(item2);
							flag = true;
							break;
						}
					}
				}
			}
			lstInfo = list;
			return list.Count;
		}

		public int GetBreamOfSelect(ref List<BreamInfo> lstInfo)
		{
			List<BreamInfo> list = new List<BreamInfo>();
			ViewPlan viewPlan = this.m_view as ViewPlan;
			if (viewPlan == null)
			{
				lstInfo = list;
				return -1;
			}
			foreach (FamilyInstance bream in this.SelectioneByRectangle())
			{
				BreamInfo item = new BreamInfo(this.m_commandData, bream, viewPlan);
				list.Add(item);
			}
			lstInfo = list;
			return list.Count;
		}

		private List<FamilyInstance> SelectioneByRectangle()
		{
			IList<Element> list = new List<Element>();
			List<FamilyInstance> list2 = new List<FamilyInstance>();
			list = this.m_uiDoc.Selection.PickElementsByRectangle();
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i].Category.Id.IntegerValue == -2001320)
				{
					LocationCurve locationCurve = list[i].Location as LocationCurve;
					if (locationCurve != null && Math.Abs(locationCurve.Curve.GetEndPoint(0).Z - locationCurve.Curve.GetEndPoint(1).Z) < 0.001 && locationCurve.Curve.Length > BreamConnectColumnGeometryToos.OneMillimeter * 200.0)
					{
						list2.Add(list[i] as FamilyInstance);
					}
				}
			}
			return list2;
		}

		private LinkedList<FamilyInstance> GetBreamOnDoc()
		{
			LinkedList<FamilyInstance> linkedList = new LinkedList<FamilyInstance>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_StructuralFraming)).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				FamilyInstance familyInstance = (FamilyInstance)element;
				LocationCurve locationCurve = familyInstance.Location as LocationCurve;
				if (locationCurve != null && !locationCurve.Curve.GetEndPoint(0).IsAlmostEqualTo(locationCurve.Curve.GetEndPoint(1)) && Math.Abs(locationCurve.Curve.GetEndPoint(0).Z - locationCurve.Curve.GetEndPoint(1).Z) < 0.001 && locationCurve.Curve.Length > BreamConnectColumnGeometryToos.OneMillimeter * 200.0)
				{
					linkedList.AddLast(familyInstance);
				}
			}
			return linkedList;
		}

		private Dictionary<Level, double> GetDocLevel()
		{
			Dictionary<Level, double> dictionary = new Dictionary<Level, double>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Levels)).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				Level level = (Level)element;
				if (!dictionary.ContainsKey(level))
				{
					dictionary.Add(level, level.Elevation);
				}
			}
			return dictionary;
		}

		private Dictionary<ViewPlan, Level> GetDocViewPlan()
		{
			Dictionary<ViewPlan, Level> dictionary = new Dictionary<ViewPlan, Level>();
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(this.m_doc);
			filteredElementCollector.WherePasses(new ElementCategoryFilter(BuiltInCategory.OST_Views)).WhereElementIsNotElementType();
			foreach (Element element in filteredElementCollector)
			{
				ViewPlan viewPlan = ((Autodesk.Revit.DB.View)element) as ViewPlan;
				if (viewPlan != null && viewPlan.GenLevel != null)
				{
					Level genLevel = viewPlan.GenLevel;
					dictionary.Add(viewPlan, genLevel);
				}
			}
			return dictionary;
		}

		private List<Level> GetNoViewPlanLevel()
		{
			List<Level> list = new List<Level>();
			new Dictionary<Level, double>();
			Dictionary<ViewPlan, Level> dictionary = new Dictionary<ViewPlan, Level>();
			Dictionary<Level, double> docLevel = this.GetDocLevel();
			dictionary = this.GetDocViewPlan();
			foreach (KeyValuePair<Level, double> keyValuePair in docLevel)
			{
				if (!dictionary.ContainsValue(keyValuePair.Key))
				{
					list.Add(keyValuePair.Key);
				}
			}
			return list;
		}

		private Level GetBreamTopLevel(FamilyInstance bream, Dictionary<Level, double> docLevel)
		{
			Curve curve = (bream.Location as LocationCurve).Curve;
			double z = curve.GetEndPoint(1).Z;
			if (curve.GetEndPoint(0).Z > z)
			{
				z = curve.GetEndPoint(0).Z;
			}
			double num = double.MaxValue;
			Level result = null;
			foreach (KeyValuePair<Level, double> keyValuePair in docLevel)
			{
				if (keyValuePair.Value - z >= 0.0 && keyValuePair.Value - z < num)
				{
					result = keyValuePair.Key;
					num = keyValuePair.Value - z;
				}
			}
			return result;
		}

		private bool IsLookElement(FamilyInstance bream, ViewPlan inViewPlan)
		{
			bool result;
			try
			{
				double num = 0.0;
				double num2 = 0.0;
                Level level = this.m_doc.GetElement(inViewPlan.GetViewRange().GetLevelId((PlanViewPlane)0)) as Level;
				if (level != null)
				{
					num = level.Elevation + inViewPlan.GetViewRange().GetOffset(0);
				}
                Level level2 = this.m_doc.GetElement(inViewPlan.GetViewRange().GetLevelId((PlanViewPlane)3)) as Level;
				if (level2 != null)
				{
                    num2 = level2.Elevation + inViewPlan.GetViewRange().GetOffset((PlanViewPlane)3);
				}
				XYZ endPoint;
				XYZ endPoint2;
				if ((bream.Location as LocationCurve).Curve.GetEndPoint(0).Z <= (bream.Location as LocationCurve).Curve.GetEndPoint(1).Z)
				{
					endPoint = (bream.Location as LocationCurve).Curve.GetEndPoint(0);
					endPoint2 = (bream.Location as LocationCurve).Curve.GetEndPoint(1);
				}
				else
				{
					endPoint = (bream.Location as LocationCurve).Curve.GetEndPoint(1);
					endPoint2 = (bream.Location as LocationCurve).Curve.GetEndPoint(0);
				}
				if (endPoint.Z >= num2 && endPoint2.Z <= num)
				{
					result = true;
				}
				else
				{
					result = false;
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private ExternalCommandData m_commandData;

		private UIDocument m_uiDoc;

		private Document m_doc;

		private Dictionary<Level, double> m_levelOfdoc = new Dictionary<Level, double>();

		private Autodesk.Revit.DB.View m_view;

		private LinkedList<FamilyInstance> m_lstDocBream = new LinkedList<FamilyInstance>();
	}
}
